package org.spring.springboot.app.sys.office.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spring.springboot.app.agent.balancelog.dao.SysOfficeBalanceLogDao;
import org.spring.springboot.app.agent.balancelog.domain.po.SysOfficeBalanceLogPO;
import org.spring.springboot.app.agent.balancelog.service.ISysOfficeBalanceLogService;
import org.spring.springboot.app.base.Constants;
import org.spring.springboot.app.base.R;
import org.spring.springboot.app.set.agenttype.domain.po.AgentTypePO;
import org.spring.springboot.app.set.agenttype.service.IAgentTypeService;
import org.spring.springboot.app.sys.area.dao.SysAreaDao;
import org.spring.springboot.app.sys.office.dao.SysOfficeDao;
import org.spring.springboot.app.sys.office.domain.bo.AgentTypeOfficeBO;
import org.spring.springboot.app.sys.office.domain.po.AgentTypeOfficePO;
import org.spring.springboot.app.sys.office.domain.po.SysOfficePO;
import org.spring.springboot.app.sys.office.domain.po.SysOfficeWalletPO;
import org.spring.springboot.app.sys.office.domain.vo.InsertSysOfficeReqVO;
import org.spring.springboot.app.sys.office.domain.vo.SysOfficeAllResVO;
import org.spring.springboot.app.sys.office.service.ISysOfficeService;
import org.spring.springboot.app.user.sysuser.dao.SysUserDao;
import org.spring.springboot.app.user.sysuser.domain.po.SysUserPO;
import org.spring.springboot.app.user.sysuser.domain.po.SysUserRolePO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

@Service
public class SysOfficeServiceImpl implements ISysOfficeService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SysOfficeServiceImpl.class);

    @Autowired
    private SysOfficeDao sysOfficeDao;
    @Autowired
    private SysAreaDao sysAreaDao;
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    IAgentTypeService agentTypeService;
    @Autowired
    private ISysOfficeBalanceLogService sysOfficeBalanceLogService;



    @Override
    public SysOfficePO find(String id) {
        return sysOfficeDao.selectByPrimaryKey(id);
    }

    @Override
    public List<SysOfficeAllResVO> findAll() {
        return sysOfficeDao.findAll();
    }

    @Override
    public List<SysOfficeAllResVO> findOfficeId(String id,String str) {
        return sysOfficeDao.findOfficeId(id,str);
    }

    @Override
    public int save(InsertSysOfficeReqVO sysOffice) {
        //创建一个po对象
        SysOfficePO sysOfficePO = new SysOfficePO();
        //把vo强转po
        BeanUtils.copyProperties(sysOffice, sysOfficePO);
        if (sysOfficePO.getParentId() == null || sysOfficePO.getParentId() == "") {
            sysOfficePO.setParentId("0");
        }
        if (sysOfficePO.getSort() == null || sysOfficePO.getSort() < 1) {
            sysOfficePO.setSort(sysOfficeDao.findMaxSortByParentId(sysOfficePO.getParentId()));
            sysOfficePO.setSort(sysOfficePO.getSort() == null ? 0 : sysOfficePO.getSort());
        }
        if (sysOfficePO.getParentIds() == null || sysOfficePO.getParentIds() == "") {
            sysOfficePO.setParentIds(sysOfficeDao.findParentsByParentId(sysOfficePO.getParentId()));
            sysOfficePO.setParentIds(sysOfficePO.getParentId().equals("0") ? "0," : sysOfficePO.getParentIds());
        }
        if (sysOfficePO.getGrade() == null || sysOfficePO.getGrade() == "") {
            sysOfficePO.setGrade(sysOfficeDao.findGradeByParentId(sysOfficePO.getParentId()));
            sysOfficePO.setGrade(sysOfficePO.getGrade() == null ? "1" : sysOfficePO.getGrade());
        }
        if (sysOfficePO.getCode() == null || sysOfficePO.getCode() ==""){
            sysOfficePO.setCode(sysAreaDao.findCodeById(sysOfficePO.getAreaId()));
        }
        sysOfficePO.preInsert();


        //插入机构代理商类型信息
        for(int i=0;i<sysOffice.getAgentType().size();i++){
            AgentTypeOfficePO agentTypeOfficePO = new AgentTypeOfficePO();
            agentTypeOfficePO.setAgentTypeId(sysOffice.getAgentType().get(i));
            agentTypeOfficePO.setOfficeId(sysOfficePO.getId());
            sysOfficeDao.insertOfficeAgentType(agentTypeOfficePO);
        }
        //插入机构信息
        return sysOfficeDao.insertSelective(sysOfficePO);
    }

    @Override
    public int update(InsertSysOfficeReqVO sysOffice) {
        //创建一个po对象
        SysOfficePO sysOfficePO = new SysOfficePO();
        //把vo强转po
        BeanUtils.copyProperties(sysOffice, sysOfficePO);
        if (sysOfficePO.getCode() == null || sysOfficePO.getCode() ==""){
            sysOfficePO.setCode(sysAreaDao.findCodeById(sysOfficePO.getAreaId()));
        }
        sysOfficePO.preUpdate();

        if (sysOffice.getAgentType() != null) {
            //修改机构代理商类型信息
            sysOfficeDao.delOfficeAgentType(sysOfficePO.getId());
            //插入机构代理商类型信息
            for (int i = 0; i < sysOffice.getAgentType().size(); i++) {
                AgentTypeOfficePO agentTypeOfficePO = new AgentTypeOfficePO();
                agentTypeOfficePO.setAgentTypeId(sysOffice.getAgentType().get(i));
                agentTypeOfficePO.setOfficeId(sysOfficePO.getId());
                sysOfficeDao.insertOfficeAgentType(agentTypeOfficePO);
            }
        }

        //存在用户需要处理用户相关的信息（机构及角色）
        if (StringUtils.isNotBlank(sysOffice.getUserId())) {
            SysUserPO user = sysUserDao.selectByPrimaryKey(sysOffice.getUserId());
            SysUserPO _userPo = new SysUserPO();
            _userPo.setId(sysOffice.getUserId());
            _userPo.setOfficeId(sysOfficePO.getId());
            _userPo.preUpdate();
            sysUserDao.updateByPrimaryKeySelective(_userPo);
            //处理用户角色
            if (sysOffice.getAgentType() != null) {
                sysUserDao.delUserAgentRoleType(sysOffice.getUserId());
                for (String typeId : sysOffice.getAgentType()) {
                    AgentTypePO type = agentTypeService.find(typeId);
                    if (type != null) {
                        SysUserRolePO p = new SysUserRolePO();
                        p.setUserId(sysOffice.getUserId());
                        p.setRoleId(type.getRoleId());
                        sysUserDao.insertUserRole(p);
                    }
                }
            }
        }

        return sysOfficeDao.updateByPrimaryKeySelective(sysOfficePO);
    }

    @Override
    public int delete(SysOfficePO sysOfficePO) {
        sysOfficePO.preDelete();
        return sysOfficeDao.updateByPrimaryKeySelective(sysOfficePO);
    }

    @Override
    public List<SysOfficeAllResVO> findAllBySysOffice(String[] type,String parent_id) {
        return sysOfficeDao.findAllBySysOffice(type,parent_id);
    }

    @Override
    public List<AgentTypeOfficeBO> findAgentTypeByOfficeId(String officeId) {
        return sysOfficeDao.findAgentTypeByOfficeId(officeId);
    }

    @Override
    public List<SysOfficeAllResVO> findOfficeChildrenByPId(String officePId,String type) {
        return sysOfficeDao.findOfficeChildrenByPId(officePId,type);
    }

    @Override
    @Transactional
    public R addOffice(InsertSysOfficeReqVO sysOffice) {
        R r = new R();
        //创建一个po对象
        SysOfficePO sysOfficePO = new SysOfficePO();
        //把vo强转po
        BeanUtils.copyProperties(sysOffice, sysOfficePO);
        if (sysOfficePO.getParentId() == null || sysOfficePO.getParentId() == "") {
            sysOfficePO.setParentId("0");
        }
        if (sysOfficePO.getSort() == null || sysOfficePO.getSort() < 1) {
            sysOfficePO.setSort(sysOfficeDao.findMaxSortByParentId(sysOfficePO.getParentId()));
            sysOfficePO.setSort(sysOfficePO.getSort() == null ? 0 : sysOfficePO.getSort());
        }
        if (sysOfficePO.getParentIds() == null || sysOfficePO.getParentIds() == "") {
            sysOfficePO.setParentIds(sysOfficeDao.findParentsByParentId(sysOfficePO.getParentId()));
            sysOfficePO.setParentIds(sysOfficePO.getParentId().equals("0") ? "0," : sysOfficePO.getParentIds());
        }
        if (sysOfficePO.getGrade() == null || sysOfficePO.getGrade() == "") {
            sysOfficePO.setGrade(sysOfficeDao.findGradeByParentId(sysOfficePO.getParentId()));
            sysOfficePO.setGrade(sysOfficePO.getGrade() == null ? "1" : sysOfficePO.getGrade());
        }
        if (sysOfficePO.getCode() == null || sysOfficePO.getCode() ==""){
            sysOfficePO.setCode(sysAreaDao.findCodeById(sysOfficePO.getAreaId()));
        }
        sysOfficePO.preInsert();
        if (sysOffice.getAgentType() != null) {
            //插入机构代理商类型信息
            for (int i = 0; i < sysOffice.getAgentType().size(); i++) {
                AgentTypeOfficePO agentTypeOfficePO = new AgentTypeOfficePO();
                agentTypeOfficePO.setAgentTypeId(sysOffice.getAgentType().get(i));
                agentTypeOfficePO.setOfficeId(sysOfficePO.getId());
                sysOfficeDao.insertOfficeAgentType(agentTypeOfficePO);
            }
        }

        //插入机构信息
        if (sysOfficeDao.insertSelective(sysOfficePO) < 1) {
            return r.fail().setMessage("保存机构失败");
        }
        //存在用户需要处理用户相关的信息（机构及角色）
        if (StringUtils.isNotBlank(sysOffice.getUserId())) {
            SysUserPO user = sysUserDao.selectByPrimaryKey(sysOffice.getUserId());
            SysUserPO _userPo = new SysUserPO();
            _userPo.setId(sysOffice.getUserId());
            _userPo.setOfficeId(sysOfficePO.getId());
            _userPo.preUpdate();
            sysUserDao.updateByPrimaryKeySelective(_userPo);
            //处理用户角色
            if (sysOffice.getAgentType() != null) {
                sysUserDao.delUserAgentRoleType(sysOffice.getUserId());
                for (String typeId : sysOffice.getAgentType()) {
                    AgentTypePO type = agentTypeService.find(typeId);
                    if (type != null) {
                        SysUserRolePO p = new SysUserRolePO();
                        p.setUserId(sysOffice.getUserId());
                        p.setRoleId(type.getRoleId());
                        sysUserDao.insertUserRole(p);
                    }
                }
            }
        }

        return r.success();
    }

    @Override
    public SysOfficePO queryAreaGeneralAgent(String areaId) {
        return sysOfficeDao.queryAreaOffice(areaId, Constants.SYS_OFFICE_TYPE_1+"");
    }

    @Override
    public SysOfficeWalletPO queryWallet(String id) {
        return sysOfficeDao.queryWallet(id);
    }

    @Override
    public int addOfficeMo(String id, BigDecimal mo, int type, String relateId,String relateExtId, String remark) {
        SysOfficeWalletPO walletPO = sysOfficeDao.queryWallet(id);
        BigDecimal balance = walletPO.getBalance();
        //添加机构费用
        walletPO.setOldBalance(balance);
        walletPO.setBalance(balance.add(mo));
        if (sysOfficeDao.updateWallet(walletPO) < 1) {
            throw new RuntimeException("操作余额失败");
        }
        insertBalanceLog(id, mo, type, relateId, relateExtId, remark);
        return 1;
    }


    @Override
    public int subOfficeMo(String id, BigDecimal mo, int type, String relateId, String relateExtId, String remark) {
        SysOfficeWalletPO walletPO = sysOfficeDao.queryWallet(id);
        BigDecimal balance = walletPO.getBalance();
        //添加机构费用
        walletPO.setOldBalance(balance);
        walletPO.setBalance(balance.subtract(mo));
        if (sysOfficeDao.updateWallet(walletPO) < 1) {
            throw new RuntimeException("操作余额失败");
        }
        insertBalanceLog(id, mo, type, relateId, relateExtId, remark);
        return 1;
    }

    private int insertBalanceLog(String id, BigDecimal mo, int type, String relateId,String relateExtId,String remark){
        //添加机构钱包日志
        SysOfficeBalanceLogPO balanceLogPO = new SysOfficeBalanceLogPO();
        balanceLogPO.setOfficeId(id);
        balanceLogPO.setType(type);
        balanceLogPO.setMoney(mo);
        balanceLogPO.setRelateId(relateId);
        balanceLogPO.setRelateExtId(relateExtId);
        balanceLogPO.setRemarks(remark);
        if (sysOfficeBalanceLogService.save(balanceLogPO) < 1) {
            throw new RuntimeException("代理商日志添加失败");
        }
        return 1;
    }
}
